<template>
  <div class="ttt-message" :class="[type, { close: isClose, center }]" :style="messageStyle" @click="closeClick">
    <div class="content" v-if="!isHTML">{{ message }}</div>
    <div class="content" v-else v-html="message"></div>
  </div>
</template>

<script lang="ts">
import { computed, defineComponent, ref } from 'vue'
import mitt from 'mitt'
import type { PropType, SetupContext, CSSProperties } from 'vue'
import type { Emitter } from 'mitt'
import type { ComponentsThemeType } from '../../types/components'

export interface MessageProps {
  message: string
  type: ComponentsThemeType
  center: boolean
  offset: number
  isHTML: boolean
  isFixed: boolean
}

export default defineComponent({
  name: 'FMessage',
  props: {
    // 消息
    message: {
      type: String as PropType<string>,
      required: true
    },
    // 类型
    type: {
      type: String as PropType<ComponentsThemeType>,
      default: 'success'
    },
    // 文字居中
    center: {
      type: Boolean as PropType<boolean>,
      default: true
    },
    // 距离顶部距离
    offset: {
      type: Number as PropType<number>,
      default: 0
    },
    // 是否是html
    isHTML: {
      type: Boolean as PropType<boolean>,
      default: false
    },
    // 是否固定位置
    isFixed: {
      type: Boolean as PropType<boolean>,
      default: true
    }
  },
  setup(props: MessageProps, ctx: SetupContext) {
    // 当前楼层数
    const currentIndex = ref<number>(0)
    // 是否关闭状态 添加关闭动画
    const isClose = ref<boolean>(false)
    // 消息监听
    const messageMitt: Emitter<{ close: string }> = mitt()

    // 关闭消息事件
    const closeMessage = (): void => {
      isClose.value = true
    }

    // 设置当前位置 根据位置计算对应的位置
    const setCurrentIndex = (val: number): void => {
      currentIndex.value = val
    }

    // 消息位置style
    const messageStyle = computed<CSSProperties>((): CSSProperties => {
      // 当固定位置时 直接忽略当前楼层位置
      const top = !props.isFixed ? currentIndex.value * 30 + props.offset : props.offset
      return {
        top: `${top}rem`
      }
    })

    // 关闭点击事件 通知服务关闭id
    const closeClick = (): void => {
      messageMitt.emit('close', ctx.attrs.id as string)
    }

    return {
      isClose,
      currentIndex,
      messageStyle,
      messageMitt,
      closeClick,
      closeMessage,
      setCurrentIndex
    }
  }
})
</script>

<style scoped lang="scss">
@import "../../scss/base";

@keyframes ttt-animation-message-enter {
  from {
    transform: translateY(-100%);
    opacity: 0;
  }
  to {
    transform: translateY(0);
    opacity: 1;
  }
}

@keyframes ttt-animation-message-leave {
  from {
    transform: translateY(0);
    opacity: 1;
  }
  to {
    transform: translateY(-10rem);
    opacity: 0;
  }
}

.ttt-message {
  width: 100vw;
  position: fixed;
  z-index: 1002;
  left: 0;
  right: 0;
  display: flex;
  flex-wrap: wrap;
  white-space: pre-wrap;
  word-break: break-word;
  align-items: center;
  line-height: 30rem;
  font-size: 28rem;
  padding: 20rem 30rem;
  box-sizing: border-box;
  border-radius: var(--base-border-radius);
  color: #fff;
  transition: top 0.3s;
  animation: ttt-animation-message-enter 0.3s forwards;

  &.center {
    justify-content: center;
  }

  &.close {
    animation: ttt-animation-message-leave 0.3s forwards;
  }

  @each $type, $color in $button-color-list {
    &.#{$type} {
      background-color: $color;
    }
  }

  > span {
    cursor: pointer;
    display: inline-block;
    width: 10rem;
    height: 10rem;
    line-height: 10rem;
    position: absolute;
    right: 10rem;
    top: 50%;
    transform: translateY(-50%);
  }
}
</style>
